
var Parent = window.dialogArguments;

Array.prototype.__indexOf__ = function(v) {
  var i = -1;
  for (var p in this) {
    if (this[p] == v) {
      i = Number(p); break;
    }
  }
  return i;
};

Array.prototype.__remove__ = function(v) {
  var i = this.__indexOf__(v);
  if (i >= 0)
    this.splice(i, 1);
  return this;
};

Array.prototype.__copy__ = function(a) {
  for (var p in this) {
    a[p] = this[p];
  }
};

function Panel() {
  this.element = document.createElement('div');
  this.element.__mark__ = "Debugger Html Element";
  this.element.style.width = "100%";
};

function Debugger() {
  this.console = null;
  this.unility = null;
  this.configure = {
    GlobalFontWeight: 'bold',
    GlobalFontFace: 'Courier New',
    NormalTextColor: '#dddddd',
    InputTextColor: 'black',
    CmdLineColor: 'black',
    ShowContextMenu: false
  };
  this.bplist = [];
  this.init();
};

Debugger.prototype.Console = function(parent) {
  this.header = null;
  this.input = null;
  this.console = null;
  this.parent = parent;
  this.command = [];
  this.index = 1;
  this.init();
};

Debugger.prototype.Console.prototype.init = function() {
  BrowserConsole.innerText = navigator.appName + '\n' + navigator.userAgent + '\n(' + navigator.platform + ',' + navigator.cpuClass + ') ' + ScriptEngine() + ' Version ' + ScriptEngineMajorVersion() + '.' + ScriptEngineMinorVersion() + '.' + ScriptEngineBuildVersion() + '\n\n\n\n';
  this.insert();
};

Debugger.prototype.Console.prototype.insert = function() {
  var header = document.createElement("p");
  var input = document.createElement("textarea");
  var console = document.createElement("div");
  with (header.style) {
    margin = "0px";
    padding = "0px";
    color = this.parent.configure.CmdLineColor;
  };
  with (input.style) {
    width = "100%";
    border = "none";
    height = "17px";
    fontFamily = this.parent.configure.GlobalFontFace;
    fontWeight = "bold";
    color = this.parent.configure.InputTextColor;
    overflowY = "hidden";
    margin = "0px";
    padding = "0px";
  };
  input.instance = this;
  header.__mark__ = input.__mark__ = "Debugger Html Element";
  header.innerText = "[" + ScriptEngine() + "@" + navigator.appName + "]";
  input.onkeydown = this.keydown;
  input.onpropertychange = function() {
    this.style.posHeight = this.scrollHeight;
    BrowserConsole.scrollTop = BrowserConsole.scrollHeight;
  };
  console.appendChild(header);
  console.appendChild(input);
  this.header = header;
  this.input = input;
  this.console = console;
  BrowserConsole.insertAdjacentElement('beforeEnd', console);
};

Debugger.prototype.Console.prototype.keydown = function(event) {
  event = event || window.event;
  if (event.keyCode == 13) {
    if (event.shiftKey) {
      //this.instance.input.style.height = (this.instance.input.clientHeight + 20) + "px";
    } else {
      if (this.instance.command.length > 10) {
        this.instance.command.pop();
      }
      var cmd = this.value;
      this.instance.command.unshift(this.value);
      this.instance.index = -1;
      switch (cmd) {
        case 'clear':
          BrowserConsole.innerText = "";
          this.instance.insert();
          break;
        case 'bl':
          if (this.instance.parent.bplist <= 0) {
            this.instance.parent.unility.write(cmd, "There is no break point");
          } else {
            this.instance.parent.unility.write(cmd, this.instance.parent.bplist);
          }
          break;
        case 'exit':
          window.close();
          this.value = "";
          break;
        case 'help':
          this.instance.parent.unility.writeLine(this.value, true);
          this.instance.parent.unility.help();
          break;
        default:
          if (cmd.indexOf('get ') == 0) {
            var href = this.instance.parent.unility.getArgumentValue(cmd)[0];
            this.instance.parent.unility.request({ url: href });
          } else if (cmd.indexOf('go ') == 0) {
            var href = this.instance.parent.unility.getArgumentValue(cmd)[0];
            if (href.indexOf('http://') < 0) {
              href = "http://" + href;
            }
            window.open(href);
          } else if (cmd.indexOf('bp ') == 0) {
            var fn = this.instance.parent.unility.getArgumentValue(cmd)[0];
            this.instance.parent.unility.bp(fn);
          } else if (cmd.indexOf('bc ') == 0) {
            var fn = this.instance.parent.unility.getArgumentValue(cmd)[0];
            this.instance.parent.unility.bc(fn);
          } else if (cmd.indexOf('ping ') == 0) {
            var url = this.instance.parent.unility.getArgumentValue(cmd)[0];
            this.instance.parent.unility.ping(url);
          } else if (cmd.length == 0 || cmd.indexOf(' ') == 0) {

          } else if (cmd.indexOf('css ') == 0) {
            var a = this.instance.parent.unility.getArgumentValue(cmd);
            this.instance.parent.unility.css(a[0], a[1]);
          } else if (cmd.indexOf('dom ') == 0) {
            var a = this.instance.parent.unility.getArgumentValue(cmd);
            this.instance.parent.unility.dom(a[0], a[1]);
          } else if (cmd.indexOf('dir ') == 0) {
            var a = this.instance.parent.unility.getArgumentValue(cmd);
            this.instance.parent.unility.dir(a[0], a[1]);
          } else if (cmd.indexOf('help ') == 0) {
            var a = this.instance.parent.unility.getArgumentValue(cmd);
            this.instance.parent.unility.help(a);
          } else if (cmd.indexOf('set ') == 0) {
            var a = this.instance.parent.unility.getArgumentValue(cmd);
            this.instance.parent.unility.set(a[0]);
          } else if (cmd.indexOf('export') == 0) {
            var a = this.instance.parent.unility.getArgumentValue(cmd);
            this.instance.parent.unility.expore(a[0]);
          } else {
            var resultValue = this.instance.execute(cmd);
            this.instance.parent.unility.write(cmd, resultValue);
          }
      };
      if (cmd.indexOf("clear") < 0 && cmd.indexOf("ping") < 0) {
        this.instance.insert();
      }
      BrowserConsole.scrollTop = BrowserConsole.scrollHeight;
      this.outerText = this.instance.parent.unility.htmlEncode(cmd);
      setTimeout(function() { try { __JSCL__.console.input.focus(); } catch (e) { } }, 500);
      return false;
    }
  } else if (event.keyCode == 38) {
    if (this.instance.index < this.instance.command.length - 1) {
      if (this.instance.index < -1) { this.instance.index = -1; }
      this.value = this.instance.command[++this.instance.index];
    } else {
      if (this.instance.command.length > 0) {
        this.value = this.instance.command[this.instance.command.length - 1];
      }
    }
  } else if (event.keyCode == 40) {
    if (this.instance.index >= this.instance.command.length) {
      this.instance.index = this.instance.command.length - 1;
    }
    if (this.instance.index > 0) {
      this.value = this.instance.command[--this.instance.index];
    } else {
      this.value = "";
      this.instance.index = -1;
    }
  };
};

Debugger.prototype.Console.prototype.execute = function(code) {
  try {
    return Parent.eval(code);
  } catch (e) {
    return e.message;
  };
};


Debugger.prototype.Unility = function(parent) {
  this.parent = parent;
};

Debugger.prototype.Unility.prototype.request = function(params) {
  var req = new ActiveXObject("Microsoft.XMLHTTP");
  req.onreadystatechange = function() {
    if (req.readyState == 4) {
      if (req.status == 200) {
        alert(req.responseText);
      }
    }
  };
  if (params.url.indexOf('http://') < 0) {
    params.url = "http://" + params.url;
  }
  try {
    req.open("GET", params.url, true);
    req.send(null);
  } catch (e) {
    this.writeLine('error: ' + e.message);
  }
};

Debugger.prototype.Unility.prototype.getArgumentValue = function(s) {
  s = s.split(' ');
  s.shift();
  var r = s.slice(0, 1);
  r = r.concat(s.slice(1, s.length).join(' '));
  return r;
};

Debugger.prototype.Unility.prototype.bp = function(fn) {
  if (!fn) { this.help(['bp']); return; }
  if (this.parent.bplist.__indexOf__(fn) >= 0) { this.writeLine('warning : function ' + fn + ' has been added'); return; }
  var sf = "window." + fn + "_bak = " + fn + ";\n" +
			    fn + "= function(){ \n" +
					"   var args=\"\";\n" +
					"   for(var i=0; i<arguments.length; i++) {\n" +
					"      args+=arguments[i] + (i == (arguments.length - 1) ? \"\" : \",\");\n" +
					"   }\n" +
					"   if(confirm(\"\\nfunction " + fn + " was called, execute it?\\n\\narguments:\\n \"+args+\" \\n\\ncaller:\\n \"+" + fn + ".caller)) {\n" +
					"      return eval(\"" + fn + "_bak('\"+args+\"')\")\n" +
					"   }\n" +
					"};\n";
  try {
    if (String(Parent.eval(fn)).indexOf('function') < 0) { this.writeLine("error: " + fn + " is not a function"); return; }
  } catch (e) {
    this.writeLine('error: ' + e.message);
    return;
  }
  try {
    Parent.eval(sf);
    this.parent.bplist.push(fn);
    this.writeLine('add break point ' + fn);
  }
  catch (e) {
    this.writeLine('error: ' + e.message);
  }
};

Debugger.prototype.Unility.prototype.bc = function(fn) {
  if (!fn) { this.help(['bc']); return }
  if (this.parent.bplist.length == 0) {
    this.writeLine('there is no break point');
  } else {
    try {
      Parent.eval("window." + fn + "=" + fn + "_bak;");
      this.parent.bplist.__remove__(fn);
      this.writeLine('delete break point ' + fn);
    } catch (e) {
      this.writeLine('error: ' + e.message);
    }
  }
};

Debugger.prototype.Unility.prototype.ping = function(href) {
  var ts = this;
  if (!href) {
    this.help(['ping']);
    ts.parent.console.insert();
    setTimeout(function() { try { __JSCL__.console.input.focus(); } catch (e) { } }, 500);
    return;
  }
  var req = new ActiveXObject("Microsoft.XMLHTTP");
  if (location.host.length > 0) { //local run
    var pathname = "";
    if (href.indexOf('/') != 0) {
      pathname = location.pathname;
    }
    href = location.host + location.port + pathname + href;
  }
  if (href.indexOf('http://') < 0 && href.indexOf('https://') < 0) {
    href = "http://" + href;
  }
  var states = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Completed'];
  var pt = null;
  req.onreadystatechange = function() {
    var t = new Date();
    ts.writeLine('Reply from : ' + href + ' status=' + states[req.readyState] + ' times=' + (t - pt));
    pt = t;
    if (req.readyState == 4) {
      if (req.status == 200) {
        ts.writeLine('Response status : ' + req.status)
      } else {
        ts.writeLine('Response status : ' + req.statusText);
      }
      ts.parent.console.insert();
      setTimeout(function() { try { __JSCL__.console.input.focus(); } catch (e) { } }, 500);
    }
  };
  pt = new Date();
  try {
    req.open("GET", href, true);
    req.send(null);
  } catch (e) {
    ts.writeLine('error: ' + e.message);
    ts.parent.console.insert();
    setTimeout(function() { try { __JSCL__.console.input.focus(); } catch (e) { } }, 500);
  }
};


Debugger.prototype.Unility.prototype.css = function(a, b) {
  if (!a) { this.help(['css']); return; }
  if (a.indexOf('(') == 0) {
    try {
      var ai = parseInt(a.substring(1, 2), 10);
      var aj = parseInt(a.substring(3, 4), 10);
      var s = Parent.document.styleSheets[ai].rules[aj];
      if (!b) {
        return this.writeLine(s.selectorText);
      }
      b = b.split("&");
      var f, c;
      for (var i = 0; i < b.length; i++) {
        c = b[i].split("=");
        if (c.length > 1) {
          s.style[c[0]] = c[1];
        }
        this.writeLine('(' + s.selectorText + ').style.' + c[0] + ' ' + s.style[c[0]]);
      }
    } catch (e) {
      this.writeLine('error: ' + e.message);
    }
    return;
  }
  var sector = this.sector(a);
  if (!sector.target && sector.collection.length <= 0) { this.writeLine('error: cant find html element'); return; }
  if (!b) { b = 'color'; }
  b = b.split('&');
  for (var i = 0; i < b.length; i++) {
    var c = b[i].split('=');
    var f = !!(c.length > 1);
    if (sector.count && sector.count > 0) {
      var sc = sector.count; sc--;
      if (sc > sector.collection.length - 1) { sc = sector.collection.length - 1; }
      sector.target = sector.collection[sc];
      try {
        if (f) { sector.target.style[c[0]] = c[1] }
        this.writeLine(a + '.style.' + c[0] + ' : ' + sector.target.currentStyle[c[0]]);
      } catch (e) {
        this.writeLine('error: cant find html element');
      }
    } else {
      for (var k = 0; k < sector.collection.length; k++) {
        sector.target = sector.collection[k];
        if (f) { sector.target.style[c[0]] = c[1] }
        this.writeLine(sector.target.nodeName + '[' + k + '].style.' + c[0] + ' : ' + sector.target.currentStyle[c[0]]);
      }
    }
  }

};

Debugger.prototype.Unility.prototype.sector = function(a) {
  var b = a.split('/');
  var c = Parent.document;
  var d = [];
  var e = [];
  var f = 1;
  for (var i = 0; i < b.length; i++) {
    try {
      var g = b[i].split(':');
      if (g.length > 1) { f = parseInt(g[1], 10); }
      if (b[i].indexOf('#') == 0) {
        c = Parent.document.getElementById(b[i].replace('#', ''));
        e.push(c);
      } else {
        e.length = 0;
        if (d.length > 0) {
          e.length = 0;
          for (var m = 0; m < d.length; m++) {
            var t = d[m];
            for (var k = 0; k < t.length; k++) {
              e.push(t[k].getElementsByTagName(g[0]));
            }
          }
          d.length = 0;
          e.__copy__(d);
        } else {
          e.push(c.getElementsByTagName(g[0]));
          e.__copy__(d);
        }
      }
    } catch (ee) {
      this.writeLine('error: ' + ee.message);
      return;
    }
  }
  if (e[0] && e[0].length) {
    var y = e[0];
    e.length = 0;
    for (var h = 0; h < y.length; h++) {
      e.push(y[h]);
    }
  }
  return { target: c, collection: e, count: parseInt(f, 10) };
};

Debugger.prototype.Unility.prototype.format = function(txt) {
  if (txt == null || txt == undefined) { throw new Error("cant get html element or property is null"); }
  return txt.toString().replace(/\\/g, '\\\\');
};

Debugger.prototype.Unility.prototype.dom = function(dom, action) {
  if (!dom) { this.help(['dom']); return; }
  var sector = this.sector(dom);
  if (!sector.target && sector.collection.length<=0) { this.writeLine('error: cant find html element'); return; }
  switch (action) {
    case '__remove__':
      this.writeLine('remove ');
      break;
    case '__swap__':
      break;
    default:
      if (!action) { action = "outerHTML"; }
      var actions = action.split('&');
      try {

        for (var k = 0; k < actions.length; k++) {
          action = actions[k];
          var av = action.split('=');
          var f = !!(av.length > 1);
          if (sector.count && sector.count > 0) {
            var sc = sector.count; sc--;
            if (sc > sector.collection.length - 1) { sc = sector.collection.length - 1; }
            sector.target = sector.collection[sc];
            if (f) { if (av[0].indexOf('on') == 0) { av[1] = new Function(av[1]); }; sector.target[av[0]] = av[1] }
            this.writeLine((sector.target.id || sector.target.nodeName) + '[' + sector.count + '].' + av[0] + ' : ' + this.format(sector.target[av[0]]));
          } else {
            for (var n = 0; n < sector.collection.length; n++) {
              sector.target = sector.collection[n];
              if (f) { if (av[0].indexOf('on') == 0) { av[1] = new Function(av[1]); }; sector.target[av[0]] = av[1] }
              this.writeLine((sector.target.id || sector.target.nodeName) + '[' + n + '].' + av[0] + ' : ' + this.format(sector.target[av[0]]));
            }
          }
        }
      } catch (e) {
        this.writeLine('error : ' + e.message);
      }
      break;
  }
};


Debugger.prototype.Unility.prototype.dir = function(a, c) {
  if (!a) { this.help(['dir']); return; }
  try {
    var b = Parent.eval(a.replace('#', ''));
  } catch (e) {
    this.writeLine('error: ' + e.message);
    return;
  }
  if (!b) { this.writeLine('error: ' + a + ' is null or undefined'); return; }
  if (b.constructor) {
    var f = !!(b instanceof Array);
    for (var p in b) {
      if (f && isNaN(p)) { continue }
      this.writeLine(p + ' : ' + b[p]);
    }
  } else {
    var count = 0;
    c = parseInt(c) || 0;
    var i = 0;
    for (var p in b) {
      if (count >= 10) { this.writeLine('...'); break; }
      if (i >= c) {
        this.writeLine(p);
        count++;
      }
      i++;
    }
  }
};

Debugger.prototype.Unility.prototype.help = function(a) {
  if (!a) {
    var cmds = ['css', 'dom', 'ping', 'clear', 'export', 'set', 'dir', 'go', 'bp', 'bc', 'bl'];
    for (var i = 0; i < cmds.length; i++) {
      this.writeLine(cmds[i]);
    }
    this.writeLine('type: "help cmd" for more help', true);
  } else {
    var helps = {
      'css': 'css #id[/element][/...][:index] color[&width=value]\n            css (a,b) color[&width=value]',
      'dom': 'dom #id[/element][/...][:index] attr[&attr=value]',
      'ping': 'ping uri',
      'clear': 'clear current console view',
      'export': 'list all the configure variables',
      'set': 'set the give configure variable value',
      'bp': 'bp function',
      'bc': 'bc function',
      'bl': 'list all break point',
      'go': 'go uri',
      'get': 'get uri',
      'dir': 'dir [object][array][json] [count]'
    };
    try {
      this.writeLine('usage : ' + helps[a[0]]);
    } catch (e) {
      this.writeLine('unregister cmd');
    }
  }

};

Debugger.prototype.Unility.prototype.set = function(a) {
  if (!a) { this.help(['set']); return; }
  try {
    a = a.split('&');
    for (var i = 0; i < a.length; i++) {
      var b = a[i].split('=');
      if (b.length > 1) { if (b[0] == "ShowContextMenu") { b[1] = Parent.eval(b[1]) }; this.parent.configure[b[0]] = b[1] }
      this.writeLine(b[0] + ' : ' + this.parent.configure[b[0]]);
    }
  } catch (e) {
    this.writeLine('error: ' + e.message);
  }
};

Debugger.prototype.Unility.prototype.expore = function(a) {
  try {
    if (!a) {
      for (var p in this.parent.configure) {
        this.writeLine(p + ' : ' + this.parent.configure[p]);
      }
    } else {
      a = a.split('&');
      for (var i = 0; i < a.length; i++) {
        this.writeLine(a[i] + ' : ' + this.parent.configure[a[i]]);
      }
    }
  } catch (e) {
    this.writeLine('error: ' + e.message);
  }
};

Debugger.prototype.Unility.prototype.htmlEncode = function(s) {
  if (s == null || s == undefined) { throw new Error('cant get html element or property is null'); }
  s = s.toString();
  s = s.replace(/&/g, "&amp;");
  s = s.replace(/</g, "&lt;");
  s = s.replace(/>/g, "&gt;");
  s = s.replace(/\"/g, "&quot;");
  s = s.replace(/\'/g, "&#34;");
  return s;
};

Debugger.prototype.Unility.prototype.writeLine = function(message) {

  BrowserConsole.insertAdjacentText('beforeEnd', '>>> ' + message + '\n');
  BrowserConsole.scrollTop = BrowserConsole.scrollHeight;
};

Debugger.prototype.Unility.prototype.write = function(cmd, result) {
  BrowserConsole.insertAdjacentText('beforeEnd', '>>> ' + result + '\n');
};


Debugger.prototype.init = function() {
  this.console = new this.Console(this);
  this.unility = new this.Unility(this);
  try {
    this.Console.input.focus();
  }
  catch (e) {
  }
};


(function() {
    if (!Parent) { alert("\nerror: This file should load as model dialog  \n\n错误: 这个文件，应该以模态对话框来加载"); return window.close(); }
    var isIE = (navigator.userAgent.indexOf('MSIE') > 0);
    if (isIE) {
      window.attachEvent("onload", function() {
        window.__JSCL__ = new Debugger();
        //document.title = Parent.location.href;
      });
      document.attachEvent("onkeydown", function(event) {
        event = event || window.event;
        if (event.keyCode == 74 && event.ctrlLeft && event.altLeft) {
          window.close();
        }
      });
      window.onunload = function() {
        Parent.__JSConsole__ = null;
      };
      window.onfocus = document.onclick = function() {
          try{
                __JSCL__.console.input.focus();
            }catch(e){ 
            }
      };
      Parent.document.attachEvent("oncontextmenu", function(event) {
        event = event || window.event;
        var target = event.srcElement;
        if (!target.id) {
          target.id = target.uniqueID;
        }
        if (!target.__mark__ && target.nodeName != "HTML") {
          __JSCL__.console.input.value = 'dom #' + target.id;
        }
        return __JSCL__.configure.ShowContextMenu
      });

      if (document.readyState == "complete") {
        if (!window.__JSCL__) { window.__JSCL__ = new Debugger(); }
      }
    } else {
      alert("We are sorry !\nCurrent version dont support other web browser, If not Internet Explore \n\n对不起，如果不是Internet explore 当前版本不支持其他浏览器.")
    }
  })();
